package org.zachary.agent.application;

import jakarta.transaction.Transactional;
import org.springframework.stereotype.Service;
import org.zachary.agent.domain.aggregate_model.token.*;
import org.zachary.agent.domain.repository.TokenRepository;
import org.zachary.agent.domain.service.TokenService;
import org.zachary.agent.infrastructure.exception.TokenValidatorException;

import java.util.Optional;

@Service
public class TokenRefreshService {
    private final TokenService tokenService;
    private final TokenRepository tokenRepository;

    public TokenRefreshService(TokenService tokenService, TokenRepository tokenRepository) {

        this.tokenService = tokenService;
        this.tokenRepository = tokenRepository;
    }

    @Transactional
    public Token refresh(String accessToken,String refreshToken,String userId,String device) throws Exception {
        if(!tokenService.validateRefreshToken(refreshToken)){
            throw new TokenValidatorException("refresh token is invalid");
        }
        DeviceId deviceId = new DeviceId(device);
        Optional<RedisTokenEntity> refreshTokenString=tokenRepository.findByUserIdAndDeviceId(userId,deviceId);
        if(refreshTokenString.isEmpty()){
             throw new TokenValidatorException("refresh token 已失效");
        }
        RedisTokenEntity entity=refreshTokenString.get();
        Token token=Token.rebuild(
                entity.getTokenId(),
                userId,
                deviceId,
                new AccessToken(accessToken,3000),
                new RefreshToken(entity.getToken(),entity.getExpires()),
                entity.getStatus()
        );
        token.refresh(tokenService);
        tokenRepository.invalidate(userId,deviceId);
        tokenRepository.save(token,userId,deviceId);
        return token;
    }

}
